package vip.manda.framework.bean;

import cn.hutool.core.annotation.AnnotationUtil;
import cn.hutool.core.util.ReflectUtil;
import vip.manda.framework.log.Log;
import vip.manda.framework.log.LogFactory;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.List;

/**
 * @author hongda.li
 * Bean对象装配器
 */
public class Assembler {

    private final BeanContainer CONTAINER;
    private final Object INSTANCE;
    private final List<Field> fields;
    private static final Log log = LogFactory.getLog();

    public Assembler(Class<?> clazz){
        CONTAINER = BeanFactory.getContainer();
        INSTANCE = CONTAINER.getBean(clazz);
        fields = Arrays.asList(ReflectUtil.getFields(clazz, field -> AnnotationUtil.hasAnnotation(field, Inject.class)));
        assemble();
    }

    private void assemble(){
        fields.forEach(field -> {
            Class<?> type = field.getType();
            Object bean = CONTAINER.getBean(type);
            if (bean == null){
                CONTAINER.getBeans()
                        .stream()
                        .filter(type::isAssignableFrom)
                        .findFirst()
                        .ifPresent(clazz -> ReflectUtil.setFieldValue(INSTANCE, field, CONTAINER.getBean(clazz)));
            }else {
                ReflectUtil.setFieldValue(INSTANCE, field, bean);
            }
            if (bean == null){
                log.error("Can't find instance[{}]", type.getName());
            }
        });
    }
}
